/////////////////////////////////////////////////////////////////////////////////////////////
// Filename: Sprite.cpp
//
//
// (c) Dave Ottley, 2012. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////
//		INCLUDES
///////////////////////////
#include <assert.h>

///////////////////////////
//		MY INCLUDES
///////////////////////////
#include "Rect.h"
#include "Sprite.h"
#include "D3DClass.h"
#include "Constants.h"
#include "Util.h"



/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						CONSTRUCTOR / COPY / DESTRUCTOR
//
/////////////////////////////////////////////////////////////////////////////////////////////

Sprite::Sprite(Coord1D fDestUpperLeft, int frameWidthInPixels, int frameHeightInPixels, 
			   Point spriteSheetPositionOnMasterAtlas, 
			   bool atlased, 
				const wchar_t * filename, 
				uint32_t numAnimationFrames, 
				uint32_t columns, uint32_t rows, float animationTimeDelta,  
				float scale, uint32_t startingFrame) :
mSourceRect(Rect(mSpriteSheetUpperLeftPosition, Coord1D(frameWidthInPixels), Coord1D(frameHeightInPixels) ) ),
mDestRect(Rect(fDestUpperLeft, Coord1D((float)frameWidthInPixels / 1920), Coord1D((float)frameHeightInPixels / 1020) ) ),
mSpriteSheetUpperLeftPosition(spriteSheetPositionOnMasterAtlas),
mScale(scale),
mAtlased(atlased),	
mTexture(0),
mNumAnimationFrames(numAnimationFrames),
mAnimationFrame(startingFrame),
mColumns(columns),
mRows(rows),
mFrameWidth(frameWidthInPixels),
mFrameHeight(frameHeightInPixels),
mAnimationTimeDelta(animationTimeDelta),
mFilePath(0),
mSpriteSheetWidthInPixels(0),
mSpriteSheetHeightInPixels(0)
{ 
	if(!mAtlased)
	{
		if(filename != 0)
		{
			mFilePath = Util::AppendAssetsDirectory(filename);
			LoadTexture(mFilePath);
		}
		mSourceRect = Rect(mSpriteSheetUpperLeftPosition, 
			Coord1D((float)frameWidthInPixels / mSpriteSheetWidthInPixels), 
			Coord1D((float)frameHeightInPixels / mSpriteSheetHeightInPixels) );
	}
}



/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						UPDATE
//	Update source and destination rect for this frame. Also, apply any entity-state based
//  rendering changes.
//
/////////////////////////////////////////////////////////////////////////////////////////////

bool Sprite::Update(float deltaX, float deltaY, float deltaScale)
{
	float left, right, top, bottom;
	
	if(!deltaX && !deltaY && !deltaScale) 
	{
		return true;
	}

	// Update and clamp the destination rect of the sprite, and update the scale
	mDestRect.mUpperLeft.x.asFloat += deltaX;
	mDestRect.mUpperLeft.y.asFloat += deltaY;
	Util::ClampFloat(mDestRect.mUpperLeft.x.asFloat, -1.0f, 1.0f);
	Util::ClampFloat(mDestRect.mUpperLeft.y.asFloat, -1.0f, 1.0f);
	
	mScale += deltaScale;

	return true;
}

/////////////////////////////////////////////////////////////////////////////////////////////
// 
//						LOAD TEXTURE
//
/////////////////////////////////////////////////////////////////////////////////////////////

bool Sprite::LoadTexture(std::wstring SpritePath)
{
	bool result;

	ReleaseTexture();

	// Initialize the texture object.
	result = D3DCls->CreateTextureFromFile(SpritePath, &mTexture);
	if(!result)
		return result;
	
	// Get correct Sprite width and height information.
	// Windows specific now but will try to implement a platform independant version later.
	HANDLE hBmp = LoadImage ( NULL, SpritePath.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );
	if ( hBmp == NULL )
		return false;  
	BITMAP bm;
	GetObject ( hBmp, sizeof(bm), &bm );
	mSpriteSheetWidthInPixels = bm.bmWidth; 
	mSpriteSheetHeightInPixels = bm.bmHeight;

	assert( ((mFrameWidth * mColumns == mSpriteSheetWidthInPixels) && (mFrameHeight * mRows == mSpriteSheetHeightInPixels))
		&& "Invalid sprite sheet dimensions. Specified width and height do not match actual image data.");

	return result;
}
